package com.grid.camera.pelco;

import java.util.Arrays;
import java.util.function.Predicate;

/** PelcoD协议响应验证器 提供多种验证策略，用于验证PelcoD协议的响应是否符合预期 */
public class PelcoDResponseValidator {

    /**
     * 创建一个组合验证器，同时检查地址匹配和校验和
     *
     * @param request 请求字节数组
     * @return 验证器，如果响应的地址匹配且校验和正确则返回true，否则返回false
     */
    public static Predicate<byte[]> addressAndChecksumMatch(byte[] request) {
        return response -> {
            if (request == null || response == null || request.length < 2 || response.length < 7) {
                return false;
            }
            return response[1] == request[1] && validateChecksum(response);
        };
    }

    /**
     * 创建一个验证器，检查响应的地址字节是否与请求的地址字节相匹配
     *
     * @param request 请求字节数组
     * @return 验证器，如果响应的地址字节与请求的地址字节相匹配则返回true，否则返回false
     */
    public static Predicate<byte[]> addressMatch(byte[] request) {
        return response -> {
            if (request == null || response == null || request.length < 2 || response.length < 2) {
                return false;
            }
            return response[1] == request[1];
        };
    }

    /**
     * 创建一个验证器，检查响应是否与请求完全相同
     *
     * @param request 请求字节数组
     * @return 验证器，如果响应与请求完全相同则返回true，否则返回false
     */
    public static Predicate<byte[]> exactMatch(byte[] request) {
        return response -> {
            if (request == null || response == null) {
                return false;
            }
            return Arrays.equals(request, response);
        };
    }

    /**
     * 创建一个验证器，检查响应的校验和是否正确
     *
     * @param response 响应字节数组
     * @return 如果响应的校验和正确则返回true，否则返回false
     */
    public static boolean validateChecksum(byte[] response) {
        if (response == null || response.length < 7) {
            return false;
        }

        // PelcoD协议校验和计算：前6个字节的和取模256
        int sum = 0;
        for (int i = 1; i < 6; i++) {
            sum += response[i] & 0xFF;
        }
        int checksum = sum % 256;

        return (checksum == (response[6] & 0xFF));
    }
}
